package ru.volgogradetzzz.net
{
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.Dictionary;
	import ru.volgogradetzzz.utils.Logger;
	/**
	 * ...
	 * @author Volgogradetzzz
	 */
	public class SequentialSwfLoader extends EventDispatcher
	{
		[Event(name = "error", type = "flash.events.ErrorEvent")]
		[Event(name = "complete", type = "flash.events.Event")]
		
		private const _PATHS_TO_LOAD:Vector.<String> = new Vector.<String>();
		private const _LOADER:Loader = new Loader();
		private const _REQUEST:URLRequest = new URLRequest();
		private const _LOADER_CONTEXT:LoaderContext = new LoaderContext();
		
		private const _APPLICATION_DOMAIN_BY_ID:Dictionary = new Dictionary();
		
		private var _isLoading:Boolean = false;
		
		private static var instance:SequentialSwfLoader;
		
		public static function getInstance():SequentialSwfLoader 
		{
			if (!instance)
			{
				instance = new SequentialSwfLoader(SINGLETON_KEY);
			}
			
			return instance;
		}
		
		public function SequentialSwfLoader(checkKey:Object) 
		{
			if (checkKey != SINGLETON_KEY)
			{
				throw(new Error("Экземпляр SequentialSwfLoader необходимо получать с помощью метода SequentialSwfLoader.getInstance()."));
			}
		
			_LOADER.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
			_LOADER.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadIOErrorHandler);
		}
		
		public function clear():void
		{
			_PATHS_TO_LOAD.length = 0;
			
			var arr:Array = new Array();
			for (var s:String in _APPLICATION_DOMAIN_BY_ID)
			{
				arr.push(s);
			}
			for each (s in arr) 
			{
				delete _APPLICATION_DOMAIN_BY_ID[s];
			}
			arr.length = 0;
			
			if (_isLoading)
			{
				_LOADER.close();
				_isLoading = false;
			}
		}
		
		public function load(id:String, path:String):void
		{
			Logger.getInstance().log(id + ' - ' + path + ' добавлен в очередь.');
			
			_PATHS_TO_LOAD.push(path + '?id=' + id);
			
			if (!_isLoading)
			{
				_isLoading = true;
				loadNext();
			}
		}
		
		public function getApplicationDomain(id:String):ApplicationDomain
		{
			return _APPLICATION_DOMAIN_BY_ID[id];
		}
		
		private function loadNext():void
		{
			if (_PATHS_TO_LOAD.length > 0)
			{
				_REQUEST.url = _PATHS_TO_LOAD.shift();
				
				Logger.getInstance().log('Начинает грузиться ' + _REQUEST.url);
				
				_LOADER_CONTEXT.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
				_LOADER.load(_REQUEST, _LOADER_CONTEXT);
			}
			else
			{
				Logger.getInstance().log('Все файлы загружены');
				
				_isLoading = false;
				dispatchEvent(new Event(Event.COMPLETE));
			}
		}
		
		private function loadCompleteHandler(event:Event):void 
		{
			Logger.getInstance().log(_REQUEST.url + ' загрузился. Осталось ' + _PATHS_TO_LOAD.length + ' файлов');
			
			_APPLICATION_DOMAIN_BY_ID[(event.target as LoaderInfo).parameters.id] = (event.target as LoaderInfo).applicationDomain;
			
			dispatchEvent(new Event((event.target as LoaderInfo).parameters.id));
			
			loadNext();
		}
		
		private function loadIOErrorHandler(event:IOErrorEvent):void 
		{
			Logger.getInstance().log('Ошибка - SequentialLoader.loadIOErrorHandler: ' + event.text, Logger.ERROR);
			
			dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, 'SequentialLoader.loadIOErrorHandler: ' + event.text));
		}
	}
}

internal const SINGLETON_KEY:Object = {};